package tpoo.server.services.impl;

import java.net.InetAddress;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import tpoo.common.dto.model.exception.users.FailedLoginException;
import tpoo.common.dto.model.users.UserDTO;
import tpoo.common.dto.model.users.status.Presence;
import tpoo.common.services.UserService;
import tpoo.server.dao.UserDAO;
import tpoo.server.model.Client;
import tpoo.server.model.Server;
import tpoo.server.model.users.User;

public class UserServiceImpl extends GenericService implements UserService{

	private Server server;
	private UserDAO userDao;

	//TODO tiene que devolver el usuario dto
	public UserDTO login(String username, String passwd, InetAddress ip,
			Integer port) throws FailedLoginException {
		getLogger().debug("login request");
		User user = this.getUserDao().getByUsername(username);
		if (user != null) {
			server.registerClient(new Client(user, ip, port));
			user.succesfullyLoggedIn();
			return null;
		} else
			throw new FailedLoginException();
	}

	public String getDescription() {
		return "Funcionalidad para un usuario";
	}

	public Float getuptime(UserDTO user) {
		User realuser = this.getServer().getLoggedUser(user.getUsername());
		return ((new Date().getTime() - realuser.getSessionStarted().getTime())/(60*1000F));
	}

	public void setServer(Server server) {
		this.server = server;
	}

	public Server getServer() {
		return server;
	}

	public void logout(UserDTO user) {
		Server server = getServer();
		server.logout(server.getLoggedUser(user.getUsername()));
	}

	public void setUserDao(UserDAO userDao) {
		this.userDao = userDao;
	}

	public UserDAO getUserDao() {
		return userDao;
	}

	public void sendMessage(UserDTO from, UserDTO to, String message) {
		User f,t;
		//User f = this.getUserDao().getByUsername(from.getUsername());
		//User t = this.getUserDao().getByUsername(to.getUsername());
		f = getServer().getLoggedUser(from.getUsername());
		t = getServer().getLoggedUser(to.getUsername());
		f.sendMessage(t,message);
	}

	public void changeStatus(UserDTO user, Presence presence) {
		getLogger().debug("Status Changing.");
		server.getLoggedUser(user.getUsername()).setPresence(presence);
	}
	
	public void addContact(UserDTO user, String contact) {
		getLogger().debug("add contact request");
		User aUser = this.getServer().getLoggedUser(user.getUsername());
		User aContact = this.getServer().getLoggedUser(contact);
		if (aContact != null)
			aUser.addContact(aContact);
		else
			getLogger().warn("El usuario que se intentó agregar como contacto de "+ aUser + " no existe en el Sistema: '"+contact+"'");
	}

	public List<UserDTO> getContacts(UserDTO user) {
		User ruser = this.getServer().getLoggedUser(user.getUsername());
		List<UserDTO> contactsDTO = new ArrayList<UserDTO>();
		List<User> contacts = ruser.getContacts();
		for (User contact : contacts)
			contactsDTO.add(new UserDTO(contact.getUsername(),contact.getPresence()));
		return contactsDTO;
	}
}
